package com.huatai.datadevelop.utils;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.huatai.datadevelop.entity.TokenConfigEntity;
import com.huatai.datadevelop.service.TemplateService;
import com.huatai.datadevelop.service.TokenConfigService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author hecai
 * @description: TODO 请求第三方接口的token 验证
 * @date 2022/11/7 14:42
 * @Version 1.0
 */
@Service
public class RequestApiTokenUtil extends TemplateService {

    @Autowired
    private TokenConfigService tokenConfigService;

    /**
     * 获取请求体token参数
     * @return
     */
    public String getApiTokenByBodyOfForm(TokenConfigEntity configEntity){
        if(configEntity!=null){
            String method = configEntity.getMethod();
            String contentType = configEntity.getContentType();
            Object object;
            Map<String, String> map = new ConcurrentHashMap<>();
            String heard = configEntity.getHeard();
            if(StringUtils.isNotBlank(heard)){
                HashMap<String,String> hashMap = JSON.parseObject(heard, HashMap.class);
                for (Map.Entry<String, String> body : hashMap.entrySet()) {
                    map.put(body.getKey(), body.getValue());
                }
            }

            HashMap hashMap =  JSON.parseObject(configEntity.getBody(),HashMap.class);
            if(method.equalsIgnoreCase("GET")){
                object = methodForGet(configEntity,map);
            }else {
                if(contentType.contains("application/json")){
                    map.put("Content-Type","application/json");
                    object = super.postByModelExchange(configEntity.getUrl(),map,hashMap ,Object.class);
                }
                else {
                    map.put("Content-Type",contentType);
                    object = super.postByModelExchangeForm(configEntity.getUrl(),map,hashMap ,Object.class);
                }
            }
            //如果是走内置参数，直接返回已经处理好的值
            String inlay = configEntity.getInlay();
            if (inlay.equalsIgnoreCase("1")){
                return object.toString();
            }
            List<String> keyPathList = new ArrayList<>();
            String[] split = configEntity.getKeyPath().split("\\.");
            for (String data:split){
                keyPathList.add(data);
            }
            return getTokenByPath(object,keyPathList);
        }
        return null;
    }

    /**
     * GET方法走的参数体
     * @param configEntity
     * @return
     */
    private Object methodForGet(TokenConfigEntity configEntity,Map<String, String> map){
        Object object = null;
        long timeStamp = DateUtil.currentSeconds();
        if(configEntity.getInlay().equalsIgnoreCase("1")){
            String inlayParameter = configEntity.getInlayParameter();
            String signData = SignUtils.getSignData(inlayParameter, timeStamp);
            return signData;
        }else {
            map.put("Content-Type","application/x-www-form-urlencoded");
            object =super.get(configEntity.getUrl()+"?"+configEntity.getParameter(),map,Object.class);
        }
        return object;
    }

    /**
     * 递归获取token数据
     * @param object
     * @param keyPath
     * @return
     */
    private String getTokenByPath(Object object,List<String> keyPath){
        String key = keyPath.get(0);
        Object token = ((LinkedHashMap) object).get(key);
        if(token!=null){
            if(keyPath.size()!=1){
                keyPath.remove(0);
                return getTokenByPath(token,keyPath);
            }
        }
        return token.toString();
    }



    /**
     * 解析json字符串
     * @param str
     * @return
     */
    public static JSONObject parseStr2JsonObj(String str) {
        JSONObject result = new JSONObject();
        JSONObject strJson = new JSONObject();
        try {
            strJson = JSONObject.parseObject(str);
        } catch (JSONException e) {
            throw new JSONException("参数格式不正确");
        }

        // 遍历每一组键值对
        for (Map.Entry<String, Object> entry : strJson.entrySet()) {
            if (StringUtils.isEmpty(entry.getValue().toString())) {
                continue;
            }

            if (isJsonArray(entry.getValue().toString())) {
                // 如果是json集合那就取集合下面的每一个分别去递归解析
                List list = new ArrayList();
                for (Object o : JSONObject.parseArray(entry.getValue().toString())) {
                    JSONObject jsonObject = o instanceof JSONObject ? ((JSONObject) o) : null;
                    list.add(parseStr2JsonObj(jsonObject.toString()));
                }
                result.put(entry.getKey(), list);
            } else if (isJsonObj(entry.getValue().toString())) {
                // 如果是json对象那就递归解析
                result.put(entry.getKey(), parseStr2JsonObj(entry.getValue().toString()));
            }else {
                // 不是json对象直接赋值
                result.put(entry.getKey(), entry.getValue());
            }
        }
        return result;
    }

    /**
     * 判断字符串是否是json集合
     * @param str
     * @return
     */
    private static boolean isJsonArray(String str) {
        if (StringUtils.isBlank(str)) {
            return false;
        }
        try {
            JSONObject.parseArray(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断字符串是否是json类型的
     * @param str
     * @return
     */
    private static boolean isJsonObj(String str) {
        if (StringUtils.isBlank(str)) {
            return false;
        }
        try {
            JSONObject.parseObject(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
